package com.aceitunaproject.server.message;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import com.aceitunaproject.server.message.processor.ActionListRequestProcessor;
import com.aceitunaproject.server.message.processor.AttackRequestProcessor;
import com.aceitunaproject.server.message.processor.BuildInstallationRequestProcessor;
import com.aceitunaproject.server.message.processor.BuildSettlementRequestProcessor;
import com.aceitunaproject.server.message.processor.HelloWorldProcessor;
import com.aceitunaproject.server.message.processor.MapAreaRefreshRequestProcessor;
import com.aceitunaproject.server.message.processor.MessageProcessor;
import com.aceitunaproject.server.message.processor.MoveRequestProcessor;
import com.aceitunaproject.server.message.processor.RecruitUnitMessageProcessor;
import com.aceitunaproject.server.player.Player;
import com.aceitunaproject.shared.message.Message;
import com.aceitunaproject.shared.message.concrete.ActionListRequest;
import com.aceitunaproject.shared.message.concrete.AttackRequest;
import com.aceitunaproject.shared.message.concrete.BuildInstallationRequest;
import com.aceitunaproject.shared.message.concrete.BuildSettlementRequest;
import com.aceitunaproject.shared.message.concrete.MapAreaRefreshRequest;
import com.aceitunaproject.shared.message.concrete.MoveRequest;
import com.aceitunaproject.shared.message.concrete.RecruitUnitRequest;
import com.aceitunaproject.shared.message.hello.HelloWorldRequest;

/**
 * (New) Default message handler implementation
 * 
 * @author Maciej Miechowicz
 */
public class DefaultMessageHandler implements MessageHandler, Serializable {

	private static final long serialVersionUID = 1209906537186889109L;
	private static final Logger logger = Logger
			.getLogger(DefaultMessageHandler.class.getName());

	private static Map<String, MessageProcessor> processors;

	/**
	 * Class constructor
	 */
	public DefaultMessageHandler() {

	}

	private static Map<String, MessageProcessor> getProcessors() {
		if (processors == null) {
			// TODO: get the processor map from ServerConfiguration and
			// eventually from configuration file
			processors = new HashMap<String, MessageProcessor>();
			processors.put(ActionListRequest.TYPE,
					new ActionListRequestProcessor());
			processors.put(MoveRequest.TYPE, new MoveRequestProcessor());
			processors.put(HelloWorldRequest.TYPE, new HelloWorldProcessor());
			processors.put(MapAreaRefreshRequest.TYPE,
					new MapAreaRefreshRequestProcessor());
			processors.put(BuildSettlementRequest.TYPE, new BuildSettlementRequestProcessor());
			processors.put(BuildInstallationRequest.TYPE, new BuildInstallationRequestProcessor());
			processors.put(RecruitUnitRequest.TYPE, new RecruitUnitMessageProcessor());
			processors.put(AttackRequest.TYPE,new AttackRequestProcessor());
		}

		return processors;
	}

	/**
	 * {@inheritDoc}
	 */
	public void handleBinaryMessage(Player player, ByteBuffer message) {
		if (message == null)
			throw new NullPointerException("Null message");
	}

	/**
	 * {@inheritDoc}
	 */
	public void handleObjectMessage(Player player, Message message) {
		if (message == null)
			throw new NullPointerException("Null message");

		MessageProcessor processor = getProcessors().get(message.getMessageType());
		if (processor == null) {
			logger.warning("Processor for message type "
					+ message.getMessageType() + " not found");
			// TODO: Consider returning exception message to the sender
			return;
		}

		processor.processMessage(player, message);
	}

}
